package com.csx.ops.service.node;

import com.ctrip.framework.apollo.openapi.client.ApolloOpenApiClient;
import com.ctrip.framework.apollo.openapi.dto.NamespaceReleaseDTO;
import com.ctrip.framework.apollo.openapi.dto.OpenItemDTO;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.yh.csx.bsf.core.http.DefaultHttpClient;
import com.yh.csx.bsf.core.http.HttpClient;
import com.yh.csx.bsf.core.util.PropertyUtils;
import com.yh.csx.bsf.core.util.StringUtils;
import lombok.*;
import org.apache.http.entity.ContentType;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 参考
 * https://blog.csdn.net/fgf00/article/details/105164434/
 */
@XStreamAlias("ApolloNode")
public class ApolloNode extends ConfigNode {
    @Getter @Setter
    @XStreamAlias("App")
    private String app;
    @Getter @Setter
    @XStreamAlias("Config")
    private String config;


    @Override
    public void exec(){
        printParam(config);
        val user = PropertyUtils.getPropertyCache("apollo.user",""); // portal url
        val portalUrl = PropertyUtils.getPropertyCache("apollo.url",""); // portal url
        val token = PropertyUtils.getPropertyCache("apollo.token",""); // 申请的token
        val env = PropertyUtils.getPropertyCache("apollo.dev","dev");
        val clusterName = PropertyUtils.getPropertyCache("apollo.clusterName","default");
        val namespaceName = PropertyUtils.getPropertyCache("apollo.namespaceName","application");
        try {
            writeLog("配置更新开始");
            ApolloOpenApiClient client = ApolloOpenApiClient.newBuilder()
                    .withPortalUrl(portalUrl)
                    .withToken(token)
                    .build();
            for (var kv : parse()) {
                if ("delete".equals(kv.todo)) {
                    client.removeItem(app, env, clusterName, namespaceName, kv.key, user);
                } else {
                    var data = new OpenItemDTO();
                    data.setKey(kv.key);
                    data.setValue(kv.value);
                    data.setComment("发布平台-创建");
                    data.setDataChangeCreatedBy(user);
                    data.setDataChangeCreatedTime(new Date());
                    client.createOrUpdateItem(app, env, clusterName, namespaceName, data);
                }
            }
            var data2 = new NamespaceReleaseDTO();data2.setReleaseTitle("发布平台-"+printTime());
            data2.setReleaseComment("发布平台-"+printTime());data2.setReleasedBy(user);
            data2.setEmergencyPublish(false);
            client.publishNamespace(app,env,clusterName,namespaceName,data2);
            writeLog("配置更新结束");
        }catch (Exception e){
            throw new StateException("配置更新失败",e);
        }
      }
    private List<ConfigInfo> parse(){
        var rs = new ArrayList<ConfigInfo>();
        var lines = this.config.split("\n");
        for(var line:lines){
            var kv = line.split("=");
            if(kv.length==2){
                var key = StringUtils.nullToEmpty(kv[0]).trim();
                var value = StringUtils.nullToEmpty(kv[1]).trim();
                if(StringUtils.isEmpty(value)) {
                    rs.add(new ConfigInfo(key, value, "delete"));
                }else {
                    rs.add(new ConfigInfo(key, value, "update"));
                }
            }else{
                var key = StringUtils.nullToEmpty(kv[0]).trim();
                rs.add(new ConfigInfo(key, "", "delete"));
            }
        }
        return rs;
    }

    @Data
    @AllArgsConstructor
    private class ConfigInfo{
         String key;
         String value;
         String todo;//delete,update
    }


    //从子节点设置对应的状态机
    public void setEngine(StateEngine engine){
        super.setEngine(engine);
    }
}
